package com.lanccj.aep.demo.ctwing.controller;

import cn.hutool.json.JSONUtil;
import com.lanccj.aep.demo.ctwing.ResponseVO;
import com.lanccj.aep.demo.ctwing.utils.DesUtils;
import com.lanccj.aep.nbiot.callback.AepMqDecodeCallback;
import com.lanccj.aep.nbiot.callback.AepMqOrginCallback;
import com.lanccj.aep.nbiot.command.AepDeviceCommandEnum;
import com.lanccj.aep.nbiot.command.AepDeviceManagementEnum;
import com.lanccj.aep.nbiot.mq.MqReport;
import com.lanccj.aep.nbiot.service.AepApiService;
import com.lanccj.aep.nbiot.service.AepMqService;
import com.lanccj.aep.nbiot.util.ResultUtil;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author Hal
 * @version 1.0
 * @description: 测试控制器
 * @date 2022-05-12 15:21
 */
@RestController
@RequestMapping("/")
public class TestController {

    Logger log = LoggerFactory.getLogger(TestController.class);
    
    @Autowired
    private AepApiService aepApiService;

    @Autowired
    private AepMqService aepMqService;

    //private static String MASTERKEY = "edc4ee8c9c2c4f389f52e0854ab20ef4";
    //private static String PRODUCTID = "15076571";
    //private static String DEVICEID = "d7d1571f0f6b4be299bdbf39a2e999e9";

    private static String MASTERKEY = "d57919c52e6743b8bf288bb7849c2249";
    private static String PRODUCTID = "15216320";

    @GetMapping("/getLocation")
    public Object getLocationByPhone (String access_number, String method) {
        //发送请求
        //String access_number="1064910000000"; //物联网卡号(149或10649号段)
        String user_id = "3wHw772Ju7zVBtetIn59pcDkOzr1Wx1N"; //用户名
        String password = "YjAQJiHVGZ0z1U9L"; //密码
        String appSecret = "A5Lme7wmD";
        log.info("access_number=" + access_number);
        log.info("user_id=" + user_id);
        log.info("password=" + password);
        log.info("appSecret=" + appSecret);
        //String method = "getLocationByPhone"; //接口名-基站粗定位接口
        String[] arr = {access_number,user_id,password,method}; //加密数组，数组所需参数根据对应的接口文档
        //key1,key2,key2为电信提供的9位长接口密钥平均分为三段所形成
        //key1为密钥前三位，key2为密钥中间三位，key3位密钥最后三位
        String key1 = appSecret.substring(0, 3);
        String key2 = appSecret.substring(3, 6);
        String key3 = appSecret.substring(6);
        log.info("appSecret=" + appSecret + "  key1=" + key1 + "  key2=" + key2 + "  key3=" + key3);
        DesUtils des = new DesUtils(); //DES加密工具类实例化
        String passwordEnc = des.strEnc(password,key1,key2,key3); //密码加密
        String sign = des.strEnc(DesUtils.naturalOrdering(arr),key1,key2,key3); //生成sign加密值
        //解析响应密文

        String base_url = "http://api.ct10649.com:9001/m2m_ec/app/location.do?method=" + method + "&access_number=" + access_number +
                "&user_id=" + user_id + "&passWord=" + passwordEnc + "&sign=" + sign;
        log.info("请求url=" + base_url);


        String data = ""; //获取的定位信息加密字符串
        try {
            data = httpGetExample(method, access_number, user_id, passwordEnc, sign);
        } catch (Exception e) {
            log.info(data + " error:" + e.getMessage());
        }


        String returnObj = null;
        try {
            returnObj = des.strDec(data,key1,key2,key3);
        } catch (Exception e) {
            log.info(data + " error:" + e.getMessage());
        }
        return returnObj; //定位数据解密，调用DES解密函数
    }

    /**
     *  消息订阅
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/api/ctwing/subscription_handle")
    public ResponseVO subscriptionHandle (HttpServletRequest request, HttpServletResponse response){

        Map<String, String[]> map = request.getParameterMap();
        Set<Map.Entry<String, String[]>> keys = map.entrySet();
        Iterator<Map.Entry<String, String[]>> it = keys.iterator();
        log.info("******************************************************************");
        log.info("----------------请求参数.start!.....");
        while (it.hasNext()){
            Map.Entry<String, String[]> itMap = it.next();
            log.info(itMap.getKey()+":"+ Arrays.toString(itMap.getValue()));
        }
        log.info("----------------请求参数.end!.....\n");

        log.info("----------------请求头.start!.....");
        Enumeration<String> enums = request.getHeaderNames();
        while (enums.hasMoreElements()) {
            String name = enums.nextElement();
            log.info((name) + ":" + request.getHeader(name));
        }
        log.info("----------------请求头.end!\n");

        int length = request.getContentLength();
        // 新建缓存存放读取数据
        byte[] buffer = new byte[length];
        ServletInputStream in = null;

        try {
            in = request.getInputStream();
            in.read(buffer, 0, length);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        log.info("----------------请求body.start!");
        try {
            log.info(new String(buffer, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        log.info("----------------请求body.end!");
        log.info("******************************************************************\n");
        return new ResponseVO<>(200, "订阅成功", "{}");
    }

    @GetMapping("/device")
    public Object device(String deviceId){
        HashMap<String,Object> params = new HashMap<>();
        params.put("MasterKey",MASTERKEY);
        params.put("productId",PRODUCTID);
        params.put("deviceId", deviceId);
        return aepApiService.invockApi(AepDeviceManagementEnum.QueryDevice, params);
    }

    @GetMapping("/deviceList")
    public Object deviceList(){
        HashMap<String,Object> params = new HashMap<>();
        params.put("MasterKey",MASTERKEY);
        params.put("productId",PRODUCTID);
        return aepApiService.invockApi(AepDeviceManagementEnum.QueryDeviceList, params);
    }

    @GetMapping("/commandList")
    public Object commandList(String deviceId){
        HashMap<String,Object> params = new HashMap<>();
        params.put("MasterKey",MASTERKEY);
        params.put("productId",PRODUCTID);
        params.put("deviceId",deviceId);
        return aepApiService.invockApi(AepDeviceCommandEnum.QueryCommandList, params);
    }

    @GetMapping("/commandListError")
    public Object commandListError(String deviceId){
        HashMap<String,Object> params = new HashMap<>();
        params.put("MasterKey",MASTERKEY);
        params.put("productId",PRODUCTID);
        params.put("deviceId",deviceId);
        return aepApiService.invockApi(AepDeviceCommandEnum.QueryCommand, params);
    }

    @GetMapping("/listen/start/orgin")
    public Object startListenOrgin(){
        aepMqService.listenerOrign(null,new AepMqOrginCallback() {
            @Override
            public void listener(String msg) {
                log.info("原始这里是控制器");
                log.info("原始msg打印消息");
                log.info(msg);
            }
        });
        return ResultUtil.defaultSuccess();
    }

    @GetMapping("/listen/start/decode")
    public Object startListenDecode(){
        aepMqService.listenerDecode(null,new AepMqDecodeCallback() {
            @Override
            public void listener(MqReport msg) {
                log.info("解密这里是控制器");
                log.info("解密msg打印消息");
                log.info(JSONUtil.toJsonStr(msg));
            }
        });
        return ResultUtil.defaultSuccess();
    }

    @GetMapping("/command/create")
    public Object commandCreate(){
        HashMap<String,Object> params = new HashMap<>();

        params.put("MasterKey","c3a8adbb4d4a43f1911143cb957ff488");
        HashMap<String,Object> body = new HashMap<>();
        body.put("deviceId","4dda216b31254302b68a72793064f331");
        body.put("operator","lanccj");
        body.put("productId","15108878");
        body.put("ttl",864000);
        //body.put("deviceGroupId",)
        //body.put("level",)
        HashMap<String,Object> content = new HashMap<>();
        content.put("dataType","2");
        content.put("payload","6A");
        body.put("content",content);

        return aepApiService.invockApi(AepDeviceCommandEnum.CreateCommand,params,body);
    }

    @GetMapping("/command/create2")
    public Object commandCreate2(){
        HashMap<String,Object> params = new HashMap<>();

        params.put("MasterKey","c3a8adbb4d4a43f1911143cb957ff488");
        HashMap<String,Object> body = new HashMap<>();
        body.put("deviceId","4dda216b31254302b68a72793064f331");
        body.put("operator","lanccj");
        body.put("productId","15108878");
        body.put("ttl",864000);
        //body.put("deviceGroupId",)
        //body.put("level",3);
        HashMap<String,Object> content = new HashMap<>();
        HashMap<String,Object> content_params = new HashMap<>();
        content_params.put("device_id","123");
        content_params.put("message_type",10);
        content_params.put("device_type","SZWL-SF-1@");
        content_params.put("device_work_mode","0");
        content.put("params",content_params);
        content.put("serviceIdentifier","device_work_mode_inquire_ack");
        body.put("content",content);

        return aepApiService.invockApi(AepDeviceCommandEnum.CreateCommand,params,body);
    }

    @GetMapping("/command/createDevice")
    public Object createDevice(){
        //TODO调用CTWING接口
        HashMap<String,Object> params = new HashMap<>();
        params.put("MasterKey","c3a8adbb4d4a43f1911143cb957ff488");
        HashMap<String,Object> body = new HashMap<>();
        body.put("deviceName","测试设备");
        body.put("deviceSn","123456789123212");
        body.put("imei","123456789123212");
        body.put("operator","test");
        HashMap<String,Object> other = new HashMap<String,Object>();
        other.put("autoObserver",0);
        body.put("other",other);
        body.put("productId",15108878);

        return aepApiService.invockApi(AepDeviceManagementEnum.CreateDevice,params,body);
    }

    public String httpGetExample(String method, String access_number, String user_id, String passwordEnc, String sign) throws Exception {
        String returnStr = "";
        HttpResponse response = null;
        CloseableHttpClient httpClient = null;
        httpClient = HttpClientBuilder.create().build();
        URIBuilder uriBuilder = new URIBuilder();
        uriBuilder.setScheme("http");// 请求用的协议，http或者https
        uriBuilder.setHost("api.ct10649.com:9001");//请求地址
        uriBuilder.setPath("/m2m_ec/app/location.do");//访问路径，可以在API文档中对应的API中找到此访问路径
        // 在请求的URL中添加参数,具体参考文档中心->API文档中“请求参数”说明
        uriBuilder.addParameter("method", method);
        uriBuilder.addParameter("access_number", access_number);
        uriBuilder.addParameter("user_id", user_id);
        uriBuilder.addParameter("passWord", passwordEnc);
        uriBuilder.addParameter("sign", sign);
        HttpGet httpGet = new HttpGet(uriBuilder.build());//构造get请求
        httpGet.addHeader("Content-Type", "application/json; charset=UTF-8");
        Map<String, String> param = new HashMap<String, String>();
        // 从URL中获取参数加到param中
        List<NameValuePair> list = uriBuilder.getQueryParams();
        for (int i = 0; i < list.size(); i++)
            param.put(list.get(i).getName(), list.get(i).getValue());

        try {
            // 发送请求
            response = httpClient.execute(httpGet);
            // 从response获取响应结果
            returnStr = new String(EntityUtils.toByteArray(response.getEntity()));
            httpClient.close();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return returnStr;
    }

}
